package com.yanqu.road.server.gameplayer.module.activity.douluodalu;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.UserActivityConditionData;
import com.yanqu.road.entity.activity.douluodalu.DouLuoDaLuPatronsBattle;
import com.yanqu.road.entity.activity.douluodalu.DouLuoDaLuPatronsBattleEnemy;
import com.yanqu.road.entity.activity.douluodalu.config.DouLuoDaLuConfig;
import com.yanqu.road.entity.activity.douluodalu.config.HideRewardDrawItem;
import com.yanqu.road.entity.activity.douluodalu.data.DouLuoDaLuPatronsTimesData;
import com.yanqu.road.entity.activity.douluodalu.data.DouLuoDaLuServerUserData;
import com.yanqu.road.entity.activity.douluodalu.enums.eDouLuoDaLuEventType;
import com.yanqu.road.entity.activity.douluodalu.log.DouLuoDaLuBattleReportData;
import com.yanqu.road.entity.activity.douluodalu.log.DouLuoDaLuEventDefendData;
import com.yanqu.road.entity.activity.douluodalu.result.BuffCalResult;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.entity.config.goods.OpenGoodsBagResult;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eMessageSubscribeType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogDouLuoDaLuTryTrain;
import com.yanqu.road.entity.messageSubscribe.entity.MessageUserNoticeData;
import com.yanqu.road.logic.activity.DouLuoDaLuLogic;
import com.yanqu.road.logic.bussiness.activity.DouLuoDaLuActivityBusiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.DouLuoDaLuPb;
import com.yanqu.road.pb.activity.douluodalu.DouLuoDaLuProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.PlayerModule;
import com.yanqu.road.server.gameplayer.module.player.PreReduceModule;
import com.yanqu.road.server.logic.activity.BaseActivityData;
import com.yanqu.road.server.manger.VipMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.douluodalu.DouLuoDaLuMgr;
import com.yanqu.road.server.manger.activity.xiuxian.XiuXianMgr;
import com.yanqu.road.server.manger.config.GoodsBagMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.messagesubscribe.MessageSubscribeMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public class DouLuoDaLuModule extends GeneralModule {

    DouLuoDaLuServerUserData userData;

    Map<Integer, DouLuoDaLuPatronsTimesData> patronsTimesDataMap;

    List<DouLuoDaLuEventDefendData> defendDataList;

    List<DouLuoDaLuBattleReportData> battleReportList;

    Random random = new Random();

    int logSize = 50;
    /**
     * 创建房间预扣的道具
     */
    public Property createTeamProperty;

    /**
     * 缓存
     */
    public int teamId;

    public int regionId;

    public DouLuoDaLuModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ActivityInfo activityInfo = DouLuoDaLuMgr.getActivityInfo();
        if(ActivityMgr.activityInShowTime(activityInfo) && DouLuoDaLuMgr.getConfig() != null) {
            userData = DouLuoDaLuActivityBusiness.getServerUserData(activityInfo.getActivityId(), getUserId());
            patronsTimesDataMap = DouLuoDaLuActivityBusiness.getDouLuoDaLuPatronsTimesDataMap(activityInfo.getActivityId(), getUserId());
            defendDataList = DouLuoDaLuActivityBusiness.getDouLuoDaLuEventDefendDataList(activityInfo.getActivityId(), getUserId());
            defendDataList.sort(new Comparator<DouLuoDaLuEventDefendData>() {
                @Override
                public int compare(DouLuoDaLuEventDefendData o1, DouLuoDaLuEventDefendData o2) {
                    long g = o1.getLogTime() - o2.getLogTime();
                    if(g > 0){
                        return 1;
                    }
                    if(g < 0){
                        return -1;
                    }
                    return 0;
                }
            });
            battleReportList = DouLuoDaLuActivityBusiness.getDouLuoDaLuBattleReportDataList(activityInfo.getActivityId(), getUserId());
            battleReportList.sort(new Comparator<DouLuoDaLuBattleReportData>() {
                @Override
                public int compare(DouLuoDaLuBattleReportData o1, DouLuoDaLuBattleReportData o2) {
                    long g = o1.getLogTime() - o2.getLogTime();
                    if(g > 0){
                        return 1;
                    }
                    if(g < 0){
                        return -1;
                    }
                    return 0;
                }
            });
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if(userData != null){
            if(userData.isInsertOption()){
                DouLuoDaLuActivityBusiness.addDouLuoDaLuServerUserData(userData);
            }else if(userData.isUpdateOption()){
                DouLuoDaLuActivityBusiness.updateDouLuoDaLuServerUserData(userData);
            }

            for (Map.Entry<Integer, DouLuoDaLuPatronsTimesData> timesDataEntry : patronsTimesDataMap.entrySet()) {
                if(timesDataEntry.getValue().isInsertOption()){
                    DouLuoDaLuActivityBusiness.addDouLuoDaLuPatronsTimesData(timesDataEntry.getValue());
                }else if(timesDataEntry.getValue().isUpdateOption()){
                    DouLuoDaLuActivityBusiness.updateDouLuoDaLuPatronsTimesData(timesDataEntry.getValue());
                }
            }
            if(defendDataList != null){
                for (int i = 0; i < defendDataList.size(); i++) {
                    DouLuoDaLuEventDefendData defendData = defendDataList.get(i);
                    if(defendData.isInsertOption()){
                        DouLuoDaLuActivityBusiness.addDouLuoDaLuEventDefendData(defendData);
                    }
                }
            }
            for (int i = 0; i < battleReportList.size(); i++) {
                DouLuoDaLuBattleReportData reportData = battleReportList.get(i);
                if(reportData.isInsertOption()){
                    DouLuoDaLuActivityBusiness.addDouLuoDaLuBattleReportData(reportData);
                }
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        syncConfig();
        initUserData();
        resetOneDay();
        syncRedDot();
    }

    /**
     * 同步配置
     */
    public void syncConfig() {
        if (!ActivityMgr.activityInShowTime(DouLuoDaLuMgr.getActivityInfo()) || DouLuoDaLuMgr.getConfig() == null) {
            return;
        }
        DouLuoDaLuProto.DouLuoDaLuConfigSyncMsg.Builder syncBuilder = DouLuoDaLuPb.buildDouLuoDaLuConfigSyncMsg(player.getLanguage(), DouLuoDaLuMgr.getConfig());
        player.sendPacket(Protocol.U_DOU_LUO_DA_LU_CONFIG_SYNC, syncBuilder);
    }

    /**
     * 初始化玩家数据
     */
    public synchronized void initUserData() {
        // 系统未解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.DouLuoDaLuActivity.getValue())) {
            return;
        }

        // 没有活动
        if (!ActivityMgr.activityInShowTime(DouLuoDaLuMgr.getActivityInfo()) || DouLuoDaLuMgr.getConfig() == null) {
            return;
        }

        ActivityInfo activityInfo = DouLuoDaLuMgr.getActivityInfo();

        // 设置微信推送时间
        try {
            MessageSubscribePushTime();
        }catch (Exception e){
            log.error("error:" + e);
        }

        // 已经有数据了
        if (userData != null && userData.getActivityId() == activityInfo.getActivityId()) {
            return;
        }

        DouLuoDaLuServerUserData tmpUserData = new DouLuoDaLuServerUserData();
        tmpUserData.setActivityId(activityInfo.getActivityId());
        tmpUserData.setUserId(getUserId());
        tmpUserData.setSendTimes(0);
        tmpUserData.setResetTime(DateHelper.getTodayZeroTimeStamp());
        tmpUserData.setInsertOption();
        userData = tmpUserData;
        patronsTimesDataMap = new ConcurrentHashMap<>();
        defendDataList = new ArrayList<>();
        battleReportList = new ArrayList<>();
    }

    /**
     * 设置推送时间
     */
    private void MessageSubscribePushTime(){
        if(!MessageSubscribeMgr.isSwitch()){
            return;
        }
        if (DouLuoDaLuMgr.getConfig() == null) {
            return;
        }
        ActivityInfo activityInfo = DouLuoDaLuMgr.getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        List<Long> timeList = new ArrayList<>();
        long startTime = DouLuoDaLuMgr.getConfig().FIGHT_DAILY_OPEN_TIME_2 * DateHelper.HOUR_MILLIONS + DateHelper.getTodayZeroTimeStamp();
        // 策划要求写死的提前时间 5 分钟
        long preTime = 5 * 60 * DateHelper.SECOND_MILLIONS;
        if (startTime - preTime <= 0) {
            return;
        }
        timeList.add(startTime - preTime);
        MessageUserNoticeData noticeData = MessageSubscribeMgr.getUserNoticeData(player.getUserId());
        final int childTypeDouLuo = 1;
        final int childTypeFengShen = 2;
        if (activityInfo.getChildType() == childTypeFengShen) {
            noticeData.setSubTime(eMessageSubscribeType.FengShenTime, timeList);
        }
        if (activityInfo.getChildType() == childTypeDouLuo) {
            noticeData.setSubTime(eMessageSubscribeType.DouLuoTime, timeList);
        }
    }

    /**
     * 同步玩家数据
     */
    public void syncUserData() {
        if (!ActivityMgr.activityInShowTime(DouLuoDaLuMgr.getActivityInfo()) || DouLuoDaLuMgr.getConfig() == null) {
            return;
        }
        DouLuoDaLuProto.DouLuoDaLuServerUserDataSyncMsg.Builder syncBuilder = DouLuoDaLuProto.DouLuoDaLuServerUserDataSyncMsg.newBuilder();
        syncBuilder.setSendTimes(userData.getSendTimes());
        syncBuilder.setFightTimes(userData.getFightTimes());
        syncBuilder.setZhuiBuTimes(userData.getZhuiBuTimes());
        player.sendPacket(Protocol.U_DOU_LUO_DA_LU_SERVER_USER_DATA_SYNC, syncBuilder);
    }

    public void syncRedDot(){
        if(userData == null || DouLuoDaLuMgr.getConfig() == null){
            return;
        }
        DouLuoDaLuProto.DouLuoDaLuCommonCrossReqMsg.Builder reqMsg = DouLuoDaLuProto.DouLuoDaLuCommonCrossReqMsg.newBuilder();
        reqMsg.setActivityId(DouLuoDaLuMgr.getActivityInfo().getActivityId());
        player.sendUnionActivityGroupPacket(Protocol.C_DOU_LUO_DA_LU_RED_DOT, reqMsg, reqMsg.getActivityId());

        //防守信息红点
        if(userData != null && battleReportList != null){
            if(battleReportList.size() > 0){
                DouLuoDaLuBattleReportData battleReportData = battleReportList.get(battleReportList.size() - 1);
                if(userData.getLastReadReportTime() < battleReportData.getLogTime()){
                    DouLuoDaLuProto.DouLuoDaLuRedDotSyncMsg.Builder redDot = DouLuoDaLuProto.DouLuoDaLuRedDotSyncMsg.newBuilder();
                    redDot.setNewReport(1);
                    player.sendPacket(Protocol.U_DOU_LUO_DA_LU_RED_DOT_SYNC, redDot);
                }
            }
        }
    }

    public Map<Integer, DouLuoDaLuPatronsTimesData> getPatronsTimesDataMap() {
        return patronsTimesDataMap;
    }

    /**
     * 每日重置
     */
    public void resetOneDay(){
        if(userData == null || DouLuoDaLuMgr.getConfig() == null){
            return;
        }
        long zeroTime = DateHelper.getTodayZeroTimeStamp();
        //派遣次数
        if(zeroTime > userData.getResetTime()){
            userData.setSendTimes(0);
            userData.setFightTimes(0);
            userData.setZhuiBuTimes(0);
            userData.setResetTime(zeroTime);
        }

        if(patronsTimesDataMap == null){
            return;
        }
        //门客次数
        for (Map.Entry<Integer, DouLuoDaLuPatronsTimesData> entry : patronsTimesDataMap.entrySet()) {
            DouLuoDaLuPatronsTimesData patronsTimesData = entry.getValue();
            if(zeroTime > patronsTimesData.getResetTime()){
                patronsTimesData.setSendTimes(0);
                patronsTimesData.setFightTimes(0);
                patronsTimesData.setZhuiBuTimes(0);
                patronsTimesData.setResetTime(zeroTime);
            }
        }
        syncUserData();
    }

    public DouLuoDaLuServerUserData getUserData() {
        return userData;
    }

    public void setUserData(DouLuoDaLuServerUserData userData) {
        this.userData = userData;
    }

    public void setPatronsTimesDataMap(Map<Integer, DouLuoDaLuPatronsTimesData> patronsTimesDataMap) {
        this.patronsTimesDataMap = patronsTimesDataMap;
    }

    public List<DouLuoDaLuProto.DouLuoDaLuGetPatronsTimesTemp> parsePatronsTemList() {
        if(patronsTimesDataMap == null){
            return new ArrayList<>();
        }
        return DouLuoDaLuPb.parsePatronsTemList(patronsTimesDataMap);
    }

    /**
     * 门客次数
     */
    public DouLuoDaLuPatronsTimesData initPatronsTimesData(int patronsId, int initVal, int type) {
        if(patronsTimesDataMap.containsKey(patronsId)){
            return patronsTimesDataMap.get(patronsId);
        }
        DouLuoDaLuPatronsTimesData patronsTimesData = new DouLuoDaLuPatronsTimesData();
        patronsTimesData.setActivityId(userData.getActivityId());
        patronsTimesData.setResetTime(DateHelper.getTodayZeroTimeStamp());
        patronsTimesData.setUserId(userData.getUserId());
        patronsTimesData.setPatronsId(patronsId);
        if(type == 1){
            patronsTimesData.setSendTimes(initVal);
        }else if(type == 3){
            patronsTimesData.setFightTimes(initVal);
        }else if(type == 2){
            patronsTimesData.setZhuiBuTimes(initVal);
        }
        patronsTimesData.setInsertOption();
        patronsTimesDataMap.put(patronsId, patronsTimesData);
        return patronsTimesData;
    }

    /**
     * 是否可下单
     *
     * @param mallId
     * @return
     */
    public boolean canPrecharge(int mallId) {
        if (!ActivityMgr.activityInShowTime(DouLuoDaLuMgr.getActivityInfo())) {
            return false;
        }
        int now = DateHelper.getCurrentSecond();
        if (userData == null) {
            return false;
        }
        if (now < (userData.getTouchMallTime(mallId) + DouLuoDaLuMgr.getConfig().MALL_KEEP_TIME)) {
            return true;
        }
        return false;
    }

    /**
     * 是否可以到账成功 不判断时间 只要有就可以到账
     *
     * @param mallId
     * @return
     */
    public boolean canChargeSucceed(int mallId) {
        ActivityInfo activityInfo = DouLuoDaLuMgr.getActivityInfo();
        if (!ActivityMgr.activityInShowTime(activityInfo)) {
            return false;
        }
        if (userData == null) {
            return false;
        }
        // 判断是否能购买
        return userData.getTouchMallMap().containsKey(mallId);
    }

    /**
     * 随机商品
     */
    public int randomMall(int now){
        MallInfo mallInfo = null;
        List<Integer> list = new ArrayList<>(DouLuoDaLuMgr.getConfig().rmbMallInfoTypeMap.keySet());
        while (list.size() > 0){
            int type = list.get(random.nextInt(list.size()));
            Map<Integer, MallInfo> typeMall = DouLuoDaLuMgr.getConfig().rmbMallInfoTypeMap.get(type);
            int vipLevel = VipMgr.getVipLv(player.getModule(PlayerModule.class).getUserInfo().getVipExp());
            for (int i = 0; i <= vipLevel; i++) {
                MallInfo tempMallInfo = typeMall.get(i);
                if(tempMallInfo != null){
                    mallInfo = tempMallInfo;
                }
            }
            if(null == mallInfo){
                list.remove(Integer.valueOf(type));
            }else {
                break;
            }
        }
        int mallId = mallInfo == null ? 0 : mallInfo.getMallId();
        if(mallId != 0){//触发礼包
            int lastTouchTime = userData.getTouchMallTime(mallId);
            if(now > lastTouchTime + DouLuoDaLuMgr.getConfig().MALL_KEEP_TIME){//超时了，购买次数清0
                userData.clearTouchMallTimes(mallId);
            }
            userData.setTouchMallTime(mallId, now);
            userData.addTouchMallTimes(mallId, 1);
        }
        return mallId;
    }

    /**
     * 商城购买
     *
     * @param mallId
     */
    public void shopBuy(int mallId) {
        try {
            if (!ActivityMgr.activityInShowTime(DouLuoDaLuMgr.getActivityInfo())) {
                return;
            }
            if (userData == null) {
                return;
            }
            userData.reduceTouchMallTimes(mallId, 1);
            if(userData.getTouchMallTimes(mallId) <= 0) {//累积购买次数为0
                userData.removeTouchMall(mallId);
            }
        } catch (Exception ex) {
            log.error(ex);
        } finally {

        }
    }

    /**
     * 试炼宝库
     */
    public int tryTrain() {
        DouLuoDaLuConfig config = DouLuoDaLuMgr.getConfig();
        //前6次是否抽隐藏大奖
        boolean excludeHide = false;
        synchronized (userData) {
            if (userData.getTotalTimes() < config.getLuckyParam().get(0)){
                excludeHide = true;
            }
            if (userData.getTotalTimes() < config.getLuckyParam().get(0) && !userData.isGetSharedBox()) {
                boolean hide = new Random().nextInt(1000) < config.getLuckyParam().get(2);
                if (hide) {
                    // 抽中，检查跨服是否有奖品
                    // 跨服再次判断
                    player.getModule(PreReduceModule.class).preReduce(config.BAOKU_COST);
                    DouLuoDaLuProto.CrossDouLuoDaLuDrawHideBoxReqMsg.Builder builder = DouLuoDaLuProto.CrossDouLuoDaLuDrawHideBoxReqMsg.newBuilder();
                    builder.setActivityId(DouLuoDaLuMgr.getActivityInfo().getActivityId());
                    builder.setServerId(GameServer.getInstance().getServerId());
                    player.sendUnionActivityGroupPacket(Protocol.C_DOU_LUO_DA_LU_DRAW_HIDE_BOX, builder, builder.getActivityId());
                    return 0;
                }
            }
        }

        synchronized (userData) {
            HideRewardDrawItem item = DouLuoDaLuMgr.getHideRewardDrawItem(config, userData.getCommonTimes(), userData.getTotalTimes(), userData.getDrawBoxList(), excludeHide, userData.getUserId());

            return handleDrawResult(config, item);
        }
    }

    /**
     * 前6次必须共享跨服的大奖，不然就是普通奖励
     */
    public int drawBoxFromCross(boolean canHide, int ret) {
        DouLuoDaLuConfig config = DouLuoDaLuMgr.getConfig();

        // 返还预扣除
        player.getModule(PreReduceModule.class).restorePreReduce(config.BAOKU_COST);
        if(ret != 0){
            return ret;
        }

        if (config == null || ActivityMgr.activityInShowPeriod(DouLuoDaLuMgr.getActivityInfo())) {
            return GameErrorCode.E_GOURD_CHILD_ACTIVITY_NO_OPEN;
        }
        if (userData == null) {
            return GameErrorCode.E_GOURD_CHILD_ACTIVITY_NO_UNLOCK;
        }

        synchronized (userData) {
            HideRewardDrawItem item;
            if (canHide) {
                item = DouLuoDaLuMgr.getHideRewardDrawItem(config.getDrawItemList());
            } else {
                item = DouLuoDaLuMgr.getHideRewardDrawItem(config, userData.getCommonTimes(), userData.getTotalTimes(), userData.getDrawBoxList(), true, userData.getUserId());
            }
            ret = handleDrawResult(config, item);
            if(ret == 0 && canHide){
                //中过大奖
                userData.setGetSharedBox(true);
            }
            return ret;
        }
    }

    /**
     * 处理盲合奖励
     */
    public int handleDrawResult(DouLuoDaLuConfig config, HideRewardDrawItem item) {

        // 扣消耗
        if (!player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(config.BAOKU_COST), eLogMoneyType.DouLuoDaLuActivity, eLogMoneyType.DouLuoDaLuTryTrainBaoKuConsume)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        if(item.isHide()){
            //重置未抽中隐藏款次数
            userData.setCommonTimes(0);
        }else {
            //未抽中隐藏款次数+1
            userData.setCommonTimes(1 + userData.getCommonTimes());
        }

        // 加奖励
        String reward = item.getItemId() + "=1";
        player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.DouLuoDaLuActivity, eLogMoneyType.DouLuoDaLuTryTrainBaoKuReward);

        userData.getDrawBoxList().add(item.getItemId());
        userData.setTotalTimes(1 + userData.getTotalTimes());

        //上传公告
        DouLuoDaLuProto.CrossUploadTryTrainRecordReqMsg.Builder upload = DouLuoDaLuProto.CrossUploadTryTrainRecordReqMsg.newBuilder();
        upload.setActivityId(DouLuoDaLuMgr.getActivityInfo().getActivityId());
        upload.setGoodsId(item.getItemId());
        //UserBaseInfo userBaseInfo = UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId());
        //upload.setPlayer(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        upload.setType(0);
        player.sendUnionActivityGroupPacket(Protocol.C_DOU_LUO_DA_LU_UPLOAD_BAO_KU_RECORD, upload, upload.getActivityId());

        DouLuoDaLuProto.DouLuoDaLuTryTrainRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuTryTrainRespMsg.newBuilder();
        respMsg.setRewards(reward);
        respMsg.setRet(0);
        player.sendPacket(Protocol.U_DOU_LUO_DA_LU_TRY_TRAIN, respMsg);

        //抽奖日志
        AutoLogMgr.add(new LogDouLuoDaLuTryTrain(userData.getActivityId(), player.getUserId(), teamId, regionId, reward));
        return 0;
    }

    public void updateConditionValue(long allScore, int type) {
        BaseActivityData baseActivityData = player.getModule(ActivityModule.class).getBaseActivityData(DouLuoDaLuMgr.getActivityInfo().getActivityId());
        if(baseActivityData != null){
            UserActivityConditionData userActivityConditionData = baseActivityData.getFirstUserActivityConditionDataByType(type);
            if(userActivityConditionData != null){
                userActivityConditionData.setValue(BigInteger.valueOf(allScore));
                player.getModule(ActivityModule.class).onActivityDataChanged(baseActivityData);
            }
        }
    }

    /**
     * 添加森林事件防守日志
     */
    public void addEventDefendData(DouLuoDaLuEventDefendData defendData){
        defendData.setInsertOption();
        if(defendDataList == null){
            return;
        }
        synchronized (defendDataList){
            if(defendDataList.size() + 1 > logSize){
                defendDataList.remove(0);
            }
            defendDataList.add(defendData);
        }
    }

    /**
     * 添加对决防守消息
     */
    public void addBattleReportData(DouLuoDaLuBattleReportData reportData){
        reportData.setInsertOption();
        if(battleReportList == null){
            return;
        }
        synchronized (battleReportList){
            if(battleReportList.size() + 1 > logSize){
                battleReportList.remove(0);
            }
            battleReportList.add(reportData);
        }
    }

    /**
     * 一键战斗，区服模拟打，上跨服结算
     * @param autoBuy 是否自动购买buff
     * @param buyItem buff项目
     * @param deathList 已打败的对方门客，（可能是打一半时，进行的一键）
     * @param patronsBattle  我方门客
     * @param enemyList  对方未打败的门客
     * @return
     */
    public int oneKeyFight(boolean autoBuy, int buyItem, int percent, List<Integer> deathList, DouLuoDaLuPatronsBattle patronsBattle, List<DouLuoDaLuPatronsBattleEnemy> enemyList, int checkTime) {
        DouLuoDaLuProto.DouLuoDaLuAutoBattleSettleReqMsg.Builder settleMsg = DouLuoDaLuProto.DouLuoDaLuAutoBattleSettleReqMsg.newBuilder();
        DouLuoDaLuConfig config = DouLuoDaLuMgr.getConfig();
        DouLuoDaLuPatronsBattleEnemy current;
        List<DouLuoDaLuPatronsBattleEnemy> battleEnemyList;
        int oldSize = deathList.size();

        battleEnemyList = new ArrayList<>(enemyList);
        //日志必须
        List<DouLuoDaLuPatronsBattleEnemy> deathPatronsList = new ArrayList<>();
        List<Integer> buffList = new ArrayList<>();
        //PreReduceModule preReduceModule = player.getModule(PreReduceModule.class);
        CurrencyModule currencyModule = player.getModule(CurrencyModule.class);
        //总消耗
        int consumeNum = 0;
        boolean enough = true;
        int buffIndex = patronsBattle.getBuyBuffIdx();
        //首次战斗
        //boolean firstBuy = deathList.size() == 0;
        int winTimes = deathList.size();
        //连胜道具奖励
        List<String> winRewards = new ArrayList<>();
        //连胜百业经验
        int patronsExp = 0;

        boolean win = false;

//        DouLuoDaLuMgr.getLogger().debug("-----------------一键战斗日志---------------------");
//        DouLuoDaLuMgr.getLogger().debug("-----------------入参---------------------");
//        DouLuoDaLuMgr.getLogger().debug("autoBuy :{}, buyItem :{}, percent : {}", autoBuy, buyItem, percent);
//        DouLuoDaLuMgr.getLogger().debug("-----------------玩家与门客---------------------");
//        DouLuoDaLuMgr.getLogger().debug("-------------初始连胜次数{}，是否[{}]有购买一次buff, 元宝数：{}---------------------", winTimes, buffIndex > 0, player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.Ingots));
//        DouLuoDaLuMgr.getLogger().debug("玩家:{},门客:{},总血量:{},当前血量:{}", player.getUserId(), patronsBattle.getPatronsId(), patronsBattle.getTotalBlood(), patronsBattle.getBlood());
//        DouLuoDaLuMgr.getLogger().debug("-----------------对手信息---------------------");
//        DouLuoDaLuMgr.getLogger().debug("总门客:{},已击败:{},未击败:{}", deathList.size() + enemyList.size(), deathList.size(), enemyList.size());
//        DouLuoDaLuMgr.getLogger().debug("-----------------对手门客---------------------");
//        for (DouLuoDaLuPatronsBattleEnemy enemyPatrons : battleEnemyList) {
//            DouLuoDaLuMgr.getLogger().debug("门客：{}, 总血量：{}，当前血量：{}", enemyPatrons.getPatronsId(), enemyPatrons.getTotalBlood(), enemyPatrons.getBlood());
//        }
//        DouLuoDaLuMgr.getLogger().debug("-----------------------------------------------------");
        int loop = 0;
        List<Integer> startBuyIdx = new ArrayList<>();
        while(patronsBattle.getBlood() > 0 && battleEnemyList.size() > 0){
            //购买buff临界值
            long buyBoundary = getBuyBoundary(percent, patronsBattle);

//            DouLuoDaLuMgr.getLogger().debug("我方门客：{}, 总血量：{}，当前血量：{}, 临界血量：{}", patronsBattle.getPatronsId(), patronsBattle.getTotalBlood(), patronsBattle.getBlood(), buyBoundary);

            int idx = random.nextInt(battleEnemyList.size());
            current = battleEnemyList.remove(idx);
            deathPatronsList.add(current);

            //购买buff
            if(patronsBattle.getBlood() <= buyBoundary && autoBuy && enough && buffIndex == 0 && loop > 0){
                //血量小于阈值，且自动购买，且够元宝
                int costNum = config.FIGHT_BUFF_COST.get(buyItem - 1);

                Property buyCost = PropertyHelper.parseStringToProperty(GameConfig.GAME_MONEY_INGOTS + "=" + (costNum + consumeNum));
                long src = patronsBattle.getBlood();
                if(currencyModule.currencyIsEnough(buyCost)){
                    consumeNum += costNum;
                    //preReduceModule.preReduce(buyCost);
                    BuffCalResult buffResult = DouLuoDaLuLogic.battleBuyBuff(config, buyItem, patronsBattle, false);
                    buffList.add(buffResult.getBuff());
//                    DouLuoDaLuMgr.getLogger().debug("非首次购买buff[{}]", buffResult.getBuff());
//                    DouLuoDaLuMgr.getLogger().debug("消耗元宝：{}", costNum);
//                    DouLuoDaLuMgr.getLogger().debug("血量增加：{}", patronsBattle.getBlood() - src);
                    startBuyIdx.add(loop);
                }else {
                    enough = false;
//                    DouLuoDaLuMgr.getLogger().debug("元宝不足，需要{}，但当前元宝：{}", costNum, player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.Ingots));
                }
            }else if(!enough){
//                DouLuoDaLuMgr.getLogger().debug("元宝不足，当前元宝：{}", player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.Ingots));
            }else if(patronsBattle.getBlood() > buyBoundary){
//                DouLuoDaLuMgr.getLogger().debug("血量充足");
            }
            buffIndex = 0;//重置初始购买状态

//            DouLuoDaLuMgr.getLogger().debug("对方门客：{}, 总血量：{}，当前血量：{}, 出战[{}]", current.getPatronsId(), current.getTotalBlood(), current.getBlood(), idx);
//            DouLuoDaLuMgr.getLogger().debug("-----------------------------------------------------");
            //PK
            win = patronsBattle.getBlood() > current.getBlood();
            if(!win){
                current.setBlood(current.getBlood() - patronsBattle.getBlood());
                patronsBattle.setBlood(0);
//                DouLuoDaLuMgr.getLogger().debug("-----------------战斗结束------------");
//                DouLuoDaLuMgr.getLogger().debug("我方门客：{}, 总血量：{}，当前血量：{}", patronsBattle.getPatronsId(), patronsBattle.getTotalBlood(), 0);
//                DouLuoDaLuMgr.getLogger().debug("对方门客：{}, 总血量：{}，当前血量：{}", current.getPatronsId(), current.getTotalBlood(), current.getBlood() - patronsBattle.getBlood());
//                DouLuoDaLuMgr.getLogger().debug("-----------------------------------------------------");
            }else {
                patronsBattle.setBlood(patronsBattle.getBlood() - current.getBlood());     //剩余血量
                current.setBlood(0);
                deathList.add(current.getPatronsId());
                winTimes++;
                //连胜奖励
                boolean hasWinReward = config.hasWinRewards(winTimes);
//                DouLuoDaLuMgr.getLogger().debug("-----------------连胜次数{}---------------------", winTimes);
//                DouLuoDaLuMgr.getLogger().debug("我方门客：{}, 总血量：{}，当前血量：{}", patronsBattle.getPatronsId(), patronsBattle.getTotalBlood(), patronsBattle.getBlood());
//                DouLuoDaLuMgr.getLogger().debug("对方门客：{}, 总血量：{}，当前血量：{}, 退出", current.getPatronsId(), current.getTotalBlood(), 0);
//                DouLuoDaLuMgr.getLogger().debug("-----------------------------------------------------");
                if(hasWinReward) {
                    GoodsInfo goodsInfo = GoodsMgr.getGoodsById(config.getWinRewardBox(winTimes));
                    if(goodsInfo != null){
                        OpenGoodsBagResult openResult = GoodsBagMgr.getRandomGoods(goodsInfo.getGoodsId());
                        if(openResult.getReward().getCountByGoodsId(GameConfig.PATRONS_BAIYE_EXP_ID).intValue() > 0){
                            patronsExp += openResult.getReward().getCountByGoodsId(GameConfig.PATRONS_BAIYE_EXP_ID).intValue();
                        }else {
                            winRewards.add(PropertyHelper.parsePropertyToString(openResult.getReward()));
                        }
//                        DouLuoDaLuMgr.getLogger().debug("-----------------获得连胜奖励：{}---------------------", PropertyHelper.parsePropertyToString(openResult.getReward()));
                    }
                }
            }
            loop++;
        }
        if(consumeNum > 0){
            settleMsg.setConsume(GameConfig.GAME_MONEY_INGOTS + "=" + consumeNum);
        }
        settleMsg.setWin(win);
        settleMsg.setPatronsId(patronsBattle.getPatronsId());
        settleMsg.setPatronsNum(deathList.size() - oldSize);
        settleMsg.setPatronsExp(patronsExp);
        settleMsg.addAllWinRewards(winRewards);
        settleMsg.setActivityId(DouLuoDaLuMgr.getActivityInfo().getActivityId());
        settleMsg.setThisTime(checkTime);
        settleMsg.addAllBuff(buffList);
        settleMsg.addAllStartBuyIdx(startBuyIdx);
        for (DouLuoDaLuPatronsBattleEnemy patronsBattleEnemy : deathPatronsList) {
            settleMsg.addPatrons(DouLuoDaLuPb.buildDouLuoDaLuBattlePatronsBlood(patronsBattleEnemy));
        }
//        DouLuoDaLuMgr.getLogger().debug("-----------------结算---------------------");
//        DouLuoDaLuMgr.getLogger().debug("-----------------win:{}---------------------", win);
//        DouLuoDaLuMgr.getLogger().debug("-----------------击败总门客:{}---------------------", deathList.size());
//        DouLuoDaLuMgr.getLogger().debug("-----------------百业总经验:{}---------------------", patronsExp);
//        DouLuoDaLuMgr.getLogger().debug("-----------------道具奖励:{}---------------------", StringUtils.listToString(winRewards, "|"));
//        DouLuoDaLuMgr.getLogger().debug("-----------------总消耗:{}---------------------", settleMsg.getConsume());
        player.sendUnionActivityGroupPacket(Protocol.C_DOU_LUO_DA_LU_ONE_KEY_FIGHT_SETTLE, settleMsg, settleMsg.getActivityId());
        return 0;
    }

    private long getBuyBoundary(int percent, DouLuoDaLuPatronsBattle patronsBattle) {
        return BigDecimal.valueOf(patronsBattle.getTotalBlood()).multiply(BigDecimal.valueOf(percent)).divide(BigDecimal.valueOf(100l), 0, BigDecimal.ROUND_UP).longValue();
    }

    /**
     * 重置派遣/出战次数
     * @param battleType 1:普通；2：追捕/挑战
     */
    public void restoreTimes(int patronsId, int battleType) {
        if(userData != null){
            synchronized (userData) {
                DouLuoDaLuPatronsTimesData timesData = patronsTimesDataMap.get(patronsId);
                if(battleType == 1){
                    if(userData.getSendTimes() > 0) {
                        userData.setSendTimes(userData.getSendTimes() - 1);
                    }
                    if(timesData != null && timesData.getSendTimes() > 0){
                        timesData.setSendTimes(timesData.getSendTimes() - 1);
                    }
                }else if(battleType == 2){
                    if(userData.getZhuiBuTimes() > 0) {
                        userData.setZhuiBuTimes(userData.getZhuiBuTimes() - 1);
                    }
                    if(timesData != null && timesData.getZhuiBuTimes() > 0){
                        timesData.setZhuiBuTimes(timesData.getZhuiBuTimes() - 1);
                    }
                }else if(battleType == 3){
                    if(userData.getFightTimes() > 0) {
                        userData.setFightTimes(userData.getFightTimes() - 1);
                    }
                    if(timesData != null && timesData.getFightTimes() > 0){
                        timesData.setFightTimes(timesData.getFightTimes() - 1);
                    }
                }
            }
        }
    }

    /**
     * 现金购买事件上传
     */
    public void uploadRechargeEvent(MallInfo mallInfo) {
        DouLuoDaLuProto.DouLuoDaLuUploadEventNoticeMsg.Builder uploadMsg = DouLuoDaLuProto.DouLuoDaLuUploadEventNoticeMsg.newBuilder();
        uploadMsg.setActivityId(DouLuoDaLuMgr.getActivityInfo().getActivityId());
        DouLuoDaLuProto.DouLuoDaLuEventNoticeTemp.Builder temp = DouLuoDaLuProto.DouLuoDaLuEventNoticeTemp.newBuilder();
        temp.setEventType(eDouLuoDaLuEventType.ForestFair.getIntValue());
        temp.setConsume(mallInfo.getMallId() + "=1");
        temp.setRewards(mallInfo.getReward());
        temp.setUserId(player.getUserId());
        uploadMsg.setEventNotice(temp);
        player.sendUnionActivityGroupPacket(Protocol.C_DOU_LUO_DA_LU_UPLOAD_EVENT_NOTICE_RECORD, uploadMsg, uploadMsg.getActivityId());
    }

    /**
     * 森林事件上传
     */
    public void uploadEventNotice(int eventType, int eventId, String rewards, String consume) {
        DouLuoDaLuProto.DouLuoDaLuUploadEventNoticeMsg.Builder uploadMsg = DouLuoDaLuProto.DouLuoDaLuUploadEventNoticeMsg.newBuilder();
        uploadMsg.setActivityId(DouLuoDaLuMgr.getActivityInfo().getActivityId());
        DouLuoDaLuProto.DouLuoDaLuEventNoticeTemp.Builder temp = DouLuoDaLuProto.DouLuoDaLuEventNoticeTemp.newBuilder();
        temp.setEventType(eventType);
        temp.setEventId(eventId);
        temp.setConsume(consume);
        temp.setRewards(rewards);
        temp.setUserId(player.getUserId());
        uploadMsg.setEventNotice(temp);
        player.sendUnionActivityGroupPacket(Protocol.C_DOU_LUO_DA_LU_UPLOAD_EVENT_NOTICE_RECORD, uploadMsg, uploadMsg.getActivityId());
    }

    /**
     * 获取森林日志-防守-被打
     */
    public DouLuoDaLuProto.DouLuoDaLuEventDefendDataRespMsg.Builder listDefendDataList() {
        DouLuoDaLuProto.DouLuoDaLuEventDefendDataRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuEventDefendDataRespMsg.newBuilder();
        for (int i = 0; i < defendDataList.size(); i++) {
            builder.addNotify(DouLuoDaLuPb.builderDouLuoDaLuEventDefendData(defendDataList.get(i)));
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 魂师对决-战报
     */
    public DouLuoDaLuProto.DouLuoDaLuBattleReportRespMsg.Builder listBattleReportList() {
        DouLuoDaLuProto.DouLuoDaLuBattleReportRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuBattleReportRespMsg.newBuilder();
        for (int i = 0; i < battleReportList.size(); i++) {
            builder.addReport(DouLuoDaLuPb.builderDouLuoDaLuBattleReportData(battleReportList.get(i)));
        }
        if(userData != null){
            userData.setLastReadReportTime(System.currentTimeMillis());
        }
        builder.setRet(0);
        return builder;
    }

    public long getTriedStoneNum() {
        if (userData != null) {
            return userData.getTriedStoneNum();
        }
        return 0;
    }

    public synchronized void  addTriedStoneNum(long num) {
        if (userData == null) {
            ActivityInfo activityInfo = DouLuoDaLuMgr.getActivityInfo();
            DouLuoDaLuServerUserData tmpUserData = new DouLuoDaLuServerUserData();
            tmpUserData.setActivityId(activityInfo.getActivityId());
            tmpUserData.setUserId(getUserId());
            tmpUserData.setSendTimes(0);
            tmpUserData.setResetTime(DateHelper.getTodayZeroTimeStamp());
            tmpUserData.setInsertOption();
            userData = tmpUserData;
            patronsTimesDataMap = new ConcurrentHashMap<>();
            defendDataList = new ArrayList<>();
            battleReportList = new ArrayList<>();
        }
        userData.setTriedStoneNum(userData.getTriedStoneNum() + num);
    }
}
